﻿// Inner Fire 游戏引擎库
// 材质类
//
// Copyright (c) 2024 by 尔西大帝. All rights reserved.
//
// 用于材质
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-12-01
#pragma once

#include <dx/core/dx_core.h>
#include <dx/core/dx_element.h>
#include <unordered_map>
#include <memory>
#include <static_string.h>
#include <dx/core/frame_resource.h>

namespace ifire::dx {

struct MaterialDesc {
  ikit::sstr name;
  ikit::sstr albedo;
  ikit::sstr normal;
  DirectX::XMFLOAT4 tint = {1.0f, 1.0f, 1.0f, 1.0f};
  DirectX::XMFLOAT3 fresnel_r0 = {0.01f, 0.01f, 0.01f};
  float roughness = 0.25f;
};

class Material : public DxElement {
public:
  Material(int index, const MaterialDesc& desc);
  Material(const Material& rhs) = delete;
  Material& operator=(const Material& rhs) = delete;
  ~Material() = default;

  // 进行一帧的数据更新
  void Update(UploadBuffer<MaterialData>* buffer);
  // 对此Material进行水体的更新
  void AnimateWaterMaterials();

public:

  // 引用的基础颜色
  ikit::sstr albedo;
  // 引用的法线贴图
  ikit::sstr normal;

  // 是否启用
  bool disable = false;

  // 漫反射纹理在SRV堆中的索引
  int diffuse_index = -1;
  // 用于法线贴图
  int normal_index = -1;
  // 用于HDRP贴图
  int hdrp_index = -1;

  // 更新标记，用于资源帧
  int frame_dirty_count = FRAME_RESOURCE_COUNT;

  // 用于着色的材质常量缓冲区数据
  DirectX::XMFLOAT4 tint = {1.0f, 1.0f, 1.0f, 1.0f};
  DirectX::XMFLOAT3 fresnel_r0 = {0.01f, 0.01f, 0.01f};
  float roughness = 0.25f;
  DirectX::XMFLOAT4X4 mat_transform = IDENTITY_4X4;
};


using MaterialPtr = std::unique_ptr<Material>;

} // namespace ifire::dx